package sicnu.cs.ich.ich.rest;

import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sicnu.cs.ich.api.common.Constants;
import sicnu.cs.ich.api.common.ResultInfo;
import sicnu.cs.ich.api.common.annotations.OperLogConfig;
import sicnu.cs.ich.api.common.enums.FileEnum;
import sicnu.cs.ich.api.domain.dto.IchDTO;
import sicnu.cs.ich.api.domain.form.IchForm;
import sicnu.cs.ich.api.domain.form.IchQueryParam;
import sicnu.cs.ich.api.domain.form.PageParam;
import sicnu.cs.ich.api.domain.vo.AdminIchVo;
import sicnu.cs.ich.common.services.IFileUploadService;
import sicnu.cs.ich.common.services.impl.RedisService;
import sicnu.cs.ich.common.util.FileUtils;
import sicnu.cs.ich.common.util.ResultInfoUtil;
import sicnu.cs.ich.ich.service.IIchRankService;
import sicnu.cs.ich.ich.service.IIchService;
import sicnu.cs.ich.ich.service.impl.BloomFilterService;
import sicnu.cs.ich.token.security.aop.HasAuth;
import sicnu.cs.ich.token.security.util.SecurityUtil;

import javax.validation.Valid;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author 沈洋 邮箱:1845973183@qq.com
 * @create 2021/11/24-15:31
 **/
@RequiredArgsConstructor
@Slf4j
@RestController
@RequestMapping("/ichs")
@OperLogConfig("非遗模块")
public class IchResource {
    private final IIchService ichService;
    private final IIchRankService ichRankService;
    private final RedisService redisService;
    private final BloomFilterService bloomFilterService;
    private static final String ICH_LIKE_PREFIX = Constants.REDIS_ICH_LIKE;
    private final IFileUploadService fileUploadService;
    private final SecurityUtil securityUtil;

    /**
     * 助力非遗
     * @param ichId 非遗id
     */
    @PostMapping("/like/{ichId}")
    public ResultInfo<Void> likeIch(@PathVariable Integer ichId) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {
        final var uid = securityUtil.getCurrentUserId();
        // Redis更新 Bit位
        redisService.setBit(ICH_LIKE_PREFIX + ichId, uid, true);
        // 更新该非遗的hit
        ichRankService.updateIchHit(ichId);
        return ResultInfoUtil.buildSuccess();
    }

    /**
     * 查询当前用户是否已点赞该非遗
     * @param ichId
     * @return
     */
    @GetMapping("/like/{ichId}")
    public ResultInfo<Boolean> getUserLikeOrNot(@PathVariable("ichId") Integer ichId) {
        var uid = securityUtil.getCurrentUserId();
        var b = redisService.getBit(ICH_LIKE_PREFIX + ichId, uid);
        return ResultInfoUtil.buildSuccess(b);
    }

    /**
     * 收藏非遗
     * @param ichId 非遗id
     */
    @GetMapping("/collect/{ichId}")
    public ResultInfo<Void> collectIch(@PathVariable Integer ichId) {
        return ichService.collectIch(ichId)?ResultInfoUtil.buildSuccess()
                : ResultInfoUtil.buildError();
    }

    /**
     * 是否收藏
     * @param ichId 非遗id
     * @return
     */
    @GetMapping("/isCollected/{ichId}")
    public ResultInfo<Void> isCollected(@PathVariable Integer ichId) {
        return ichService.isCollected(ichId) ?
                ResultInfoUtil.buildError("已收藏") : ResultInfoUtil.buildSuccess("未收藏");
    }

    /**
     * 收藏的非遗
     * @param param
     * @return
     */
    @PostMapping("/collects")
    public ResultInfo<PageInfo<IchDTO>> collects(@Valid  @RequestBody PageParam param) {
        return ResultInfoUtil.buildSuccess(ichService.getFavoriteIchs(param));
    }

    /**
     * 从收藏中删除非遗
     * @param ichId 非遗id
     * @return
     */
    @DeleteMapping("/collects/{ichId}")
    public ResultInfo<Void> collects(@PathVariable("ichId")Integer ichId) {
        if (ichId == null) return ResultInfoUtil.buildError("参数错误");
        return ichService.deleteFavoriteIch(ichId) ?
                ResultInfoUtil.buildSuccess() : ResultInfoUtil.buildError();
    }

    /**
     * 获取非遗分页
     * @param param 分页参数
     * @return
     */
    @PostMapping("/admin/ich")
    @HasAuth("ich:management")
    public ResultInfo<PageInfo<IchDTO>> getIchs(@RequestBody IchQueryParam param){
        if ("".equals(param.getKey())){
            param.setKey(null);
        }
        var dtos = ichService.getIchDTOS(param);
        return ResultInfoUtil.buildSuccess(dtos);
    }

    /**
     * 获取非遗详情（管理员）
     * @param ichId
     * @return
     * @throws InterruptedException
     */
    @GetMapping("/admin/ich/{ichId}")
    @HasAuth("ich:management")
    public ResultInfo<AdminIchVo> getIch(@PathVariable Integer ichId) throws InterruptedException {
        // 布隆过滤器筛选
        if (!bloomFilterService.ichIdExist(ichId)) {
            return ResultInfoUtil.buildError("无id为" + ichId + "的非遗。");
        }
        AdminIchVo ich = ichService.getAdminIchVo(ichId);
        if (ich == null) {
            return ResultInfoUtil.buildError("无id为" + ichId + "的非遗。");
        }
        return ResultInfoUtil.buildSuccess(ich);
    }

    /**
     * 新增非遗
     * @param ichForm 非遗表单
     * @return
     */
    @PutMapping("/admin/ich")
    @HasAuth("ich:management:add")
    public ResultInfo<Void> addIch(@Valid @RequestBody IchForm ichForm){
        log.info(ichForm.toString());
        if (ichService.addIch(ichForm)) {
            return ResultInfoUtil.buildSuccess("添加成功");
        }return ResultInfoUtil.buildError("添加失败请重试");
    }

    /**
     * 非遗新增影集
     * @param files 影集
     * @param ichId 非遗id
     */
    @PostMapping("/admin/ich/images/{ichId}")
    @HasAuth("ich:management:add")
    public ResultInfo<Void> addIchImage(MultipartFile[] files, @PathVariable Integer ichId) throws IOException {
        if (!ichService.isIchExisted(ichId)) {
            return ResultInfoUtil.buildError("非遗信息不存在");
        }
        var fileList = FileUtils.isImage(files);
        // 七牛云不支持批量上传，只能挨个上传
        var keys = new ArrayList<String>();
        for (MultipartFile file : fileList) {
            keys.add(fileUploadService.uploadFile((FileInputStream) file.getInputStream(), FileEnum.ICH,file.getOriginalFilename()));
        }
        if (ichService.addIchImages(ichId,keys)) {
            return ResultInfoUtil.buildSuccess("上传成功");
        }return ResultInfoUtil.buildError("上传失败");
        // 校验图片
        //FileUtils.isImage(Arrays.stream(files).map(MultipartFile::getContentType).collect(Collectors.toList()));
    }

    /**
     * 上传非遗封面图片
     * @param ichId 非遗id
     * @param file 非遗图
     */
    @PostMapping("/admin/ich/coverImg/{ichId}")
    @HasAuth("ich:management:add")
    public ResultInfo<Void> updateIchImage(@PathVariable Integer ichId, @RequestParam MultipartFile file) throws IOException {
        // 校验文件是否为PNG、JPG
        if (!FileUtils.isImage(file)) {
            return ResultInfoUtil.buildError("只支持上传JPG、PNG");
        // 校验文件大小是否超超过3MB
        }else if (file.getSize()> FileUtils.mbTob(3)) {
            return ResultInfoUtil.buildError("文件大小不能超过3MB");
        }
        // 判断非遗是否存在
        boolean existed = ichService.isIchExisted(ichId);
        if (!existed){
            return ResultInfoUtil.buildError("非遗不存在");
        }
        return ichService.updateIchCoverImage(file,ichId)?ResultInfoUtil.buildSuccess("操作成功")
                : ResultInfoUtil.buildError("操作失败");
    }
}
